/*
 * Copyright (c) 2009-2013 EvTech Project
 * All rights reserved.
 * 
 * This file is part of Game packet.
 *
 * Game packet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version.
 *
 * Game packet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Game packet.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package fi.honkalampisaatio.game.selection;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.HashMap;

import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.xml.bind.JAXBException;

import fi.honkalampisaatio.game.game.LanguageResource;
import fi.honkalampisaatio.game.game.MediaResource;
import fi.honkalampisaatio.game.xml.SettingsReader;
import fi.honkalampisaatio.game.xml.UserSetting;


public class UserSelection extends JPanel {

	private static final long serialVersionUID = -1100607515971435109L;

	private SelectionListener listener = null;
	

	protected int iconHeight = 80;
	protected int iconWidth = 100;
	private static final String BACKBUTTON_IMAGE = "./settings/backbutton.gif";
	private String backButtonText;

	private int userCount;
	private HashMap<SelectionButton, UserSetting> userMap = new HashMap<SelectionButton, UserSetting>();
	private JPanel userPanel;

	public UserSelection(boolean isBackButton, boolean isExitButton) {
		refreshLanguage();
		init(isBackButton, isExitButton);
	}


	public void refreshLanguage()
	{
		LanguageResource dictionary = LanguageResource.getInstance();
		if(dictionary!=null)
			backButtonText = dictionary.get("CANCELBUTTON_TEXT");
		if(backButtonText==null || backButtonText.isEmpty())
			backButtonText = "Palaa";
	}

	public void setForeground(Color color)
	{
		super.setForeground(color);
		Component[] compList = this.getComponents();
		for(int i=0;i<compList.length;i++)
		{
			compList[i].setForeground(color);
		}
	}

	public void setFont(Font font)
	{
		super.setFont(font);
		Component[] compList = this.getComponents();
		for(int i=0;i<compList.length;i++)
		{
			float fontSize = 12;
			if(compList[i] instanceof JButton)
			{
				fontSize = ((JButton)compList[i]).getFont().getSize2D();
			}
			compList[i].setFont(font.deriveFont(fontSize));
		}
	}


	private JButton createExitButton()
	{
		JButton exitButton;
		ImageIcon btnIcon = createImageIcon("./settings/exitbutton.gif", "Lopeta peli");
		if(btnIcon!=null) {
			exitButton = new JButton("Lopeta peli", btnIcon);
		}
		else {
			exitButton = new JButton("Lopeta peli");
		}
		exitButton.setFocusable(false);
		exitButton.setVerticalTextPosition(AbstractButton.BOTTOM);
		exitButton.setHorizontalTextPosition(AbstractButton.CENTER);
		exitButton.addActionListener(
			    new ActionListener() {
			        public void actionPerformed(ActionEvent e) {
						System.exit(0);
			        }
			    }
		);
		
		return exitButton;
	}
	
	private void init(boolean isBackButton, boolean isExitButton) {
		
		File folder = new File(SelectionFrame.USERSFOLDER);
		    
		if (folder.exists()) {

		    File[] listOfFiles = folder.listFiles();
		    
			Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		    int gridColumns = (int)(Math.sqrt(listOfFiles.length)+1);
			this.setLayout(new BorderLayout());

		    if(isExitButton || isBackButton)
		    {
				this.iconHeight = (int) (screenSize.height * 0.08f);
				this.iconWidth = (int) (screenSize.width * 0.08f);
			    JPanel controlButtonPanel = new JPanel();
			    this.add(controlButtonPanel, BorderLayout.PAGE_START);
			    controlButtonPanel.setLayout(new BorderLayout());
			    if(isExitButton)
			    {
			    	controlButtonPanel.add(createExitButton(), BorderLayout.LINE_END);
			    }

				//add back button
				if(isBackButton)
				{
					controlButtonPanel.add(generateBackButton(BACKBUTTON_IMAGE, backButtonText), BorderLayout.LINE_START);
				}
		    }

		    userPanel = new JPanel();
		    this.add(userPanel, BorderLayout.CENTER);
		    userPanel.setLayout(new GridLayout(gridColumns, gridColumns));
			this.iconHeight = (int) (screenSize.height * 0.8f / gridColumns);
			this.iconWidth = (int) (screenSize.width * 0.8f / gridColumns);
		    for (int i = 0; i < listOfFiles.length; i++) {
		      if (listOfFiles[i].isFile()) {
		    	  String filename = listOfFiles[i].getName();
		    	  System.out.println(filename);
		    	  String ext = filename.substring(filename.lastIndexOf('.')+1,filename.length());
		    	  System.out.println(ext);
		    	if (ext.equalsIgnoreCase("xml") ) {  
			        System.out.println("lisätään");
			        
			        userPanel.add(generateSelectionButton(listOfFiles[i]));
		      	}
		      }
		    }	
		}
		
	}

	/**
	 * Generoidaan nappi, jolla parametrina saadussa tiedostossa
	 * määritelty pelaaja saadaan valikkoon...
	 * @param file
	 */
	private Component generateSelectionButton(File file) {
		JButton btn = null;
		UserSetting user = null; 
		try {
			user = (UserSetting) SettingsReader.getInstance().readSettings(
					file.getPath(), UserSetting.class);
		} catch (JAXBException e) {
			e.printStackTrace();
			System.exit(0);
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(0);
		}
		if(user.getUserFolder()==null || user.getUserFolder().trim().isEmpty())
		{
			int index = file.getName().lastIndexOf('.');
			if (index>0&& index <= file.getName().length() - 2 ) {
					user.setUserFolder("./data/"+file.getName().substring(0, index)+"/");
		      }  
		}
		btn = new SelectionButton(user.getName(), user.getMenuImage());
		final UserSetting userSetting = user;
		btn.addActionListener(
			    new ActionListener() {
			        public void actionPerformed(ActionEvent e) {
			            btnClicked(e, userSetting);
			        }
			    }
		);
		btn.setFocusable(false);
		btn.setVerticalTextPosition(AbstractButton.BOTTOM);
		btn.setHorizontalTextPosition(AbstractButton.CENTER);
		
		return btn;
	}

	/**
	 * Generoidaan nappi, jolla päästään valikossa takaisin
	 */
	private Component generateBackButton(String path, String description) {
		ImageIcon btnIcon = createImageIcon(path, description);
		JButton btn = null;
		if(btnIcon!=null) {
			btn = new JButton(description, btnIcon);
		}
		else {
			btn = new JButton(description);
		}
		btn.addActionListener(
			    new ActionListener() {
			        public void actionPerformed(ActionEvent e) {
			        	UserSelectionEvent se = new UserSelectionEvent(this,null);
						fireSelectionEvent(se);
			        }
			    }
		);
		btn.setFocusable(false);
		btn.setVerticalTextPosition(AbstractButton.BOTTOM);
		btn.setHorizontalTextPosition(AbstractButton.CENTER);
		return btn;
	}

	/** Returns an ImageIcon, or null if the path was invalid. */
	protected ImageIcon createImageIcon(String path, String description) {
		MediaResource mr = MediaResource.getInstance();
		int width, height;
		BufferedImage img = null;
		if(!mr.containsKey(path))
		{
			mr.setImage(path);
		}
		img = mr.get(path);
		if(img.getWidth()/this.iconWidth > img.getHeight()/this.iconHeight) {
			width = this.iconWidth;
			height = -1;
		}
		else {
			width = -1;
			height = this.iconHeight;
		}
        return new ImageIcon(img.getScaledInstance(width, height, 
        		Image.SCALE_FAST), description);
	}
	
	protected void btnClicked(ActionEvent e, UserSetting userSetting) {
    	if(userMap.size()==this.userCount) {
    		return;
    	}
    	
    	if(!(e.getSource() instanceof SelectionButton)) {
    		return;
    	}
    	SelectionButton btn = (SelectionButton)e.getSource();
    	if(userMap.containsKey(btn)) {
    		userMap.remove(btn);
    		btn.setUser(null);
    		System.out.println(userSetting.getName() + " unselected");
    	}
    	else {
        	userMap.put(btn, userSetting);
    		String userNumber = "P " + userMap.size();
    		btn.setUser(userNumber);
    		System.out.println(userSetting.getName() + " selected for " + userNumber);
    	}
    	if(userMap.size()==this.userCount) {
    		ArrayList<UserSetting> userList = new ArrayList<UserSetting>(userMap.values());
    		final UserSelectionEvent se = new UserSelectionEvent(this, userList);

			if(userCount>1) //show player choice
			{
				Thread t = new Thread(new Runnable() {

					@Override
					public void run() {
						try {
							Thread.sleep(200);
						} catch (InterruptedException e1) {
							e1.printStackTrace();
						}
			    		fireSelectionEvent(se);
					}});
				t.start();
			}
			else //do not show "p1"
			{
	    		fireSelectionEvent(se);
			}
    	}
	}
	
	public void addSelectionListener(SelectionListener  listener) {
		this.listener = listener;
	}
	
	public void removeSelectionListener(SelectionListener listener) {
		if (this.listener == listener) {
			this.listener = null;
		}
	}
	
	private void fireSelectionEvent(EventObject se) {
		if (this.listener != null)
			this.listener.selectionEventOccurred(se);
	}

	public void setUserCount(int userCount) {
		clearSelections();
		this.userCount = userCount;
	}

	
	public void clearSelections() {
		Component[] components = userPanel.getComponents();
		for(int i=0; i<components.length; i++) {
			if(components[i] instanceof SelectionButton) {
				((SelectionButton)components[i]).setUser(null);
			}
		}
		userMap.clear();
	}
}